Skip to content

feat: add options to restrict certain namespaces to certain login methods#2876

Open
JivusAyrus wants to merge 33 commits into
mainfrom
suvij/eng-9245-controlplane-different-auth-providers-for-different
Open

feat: add options to restrict certain namespaces to certain login methods#2876
JivusAyrus wants to merge 33 commits into
mainfrom
suvij/eng-9245-controlplane-different-auth-providers-for-different

Conversation

@JivusAyrus
Copy link
Copy Markdown
Member

@JivusAyrus JivusAyrus commented May 20, 2026

Summary by CodeRabbit

  • New Features

    • Multi-provider OIDC management and per-namespace SSO mapping APIs; sessions/WhoAmI now include login method
  • Security Improvements

    • RBAC tightened: analytics, graphs, proposals, persisted-ops, cache-warmers and other endpoints now enforce IdP/namespace access gates; auth contexts now carry login-method and IdP-derived namespace allowlists
  • UI/UX Enhancements

    • Namespace SSO admin page, updated SSO settings, login-method shown in user menu, namespace selector and empty-state reflect gating
  • Chores

    • DB migration and schema additions to support namespace SSO mappings

Review Change Stack

Checklist

  • I have discussed my proposed changes in an issue and have received approval to proceed.
  • I have followed the coding standards of the project.
  • Tests or benchmarks have been added or updated.
  • Documentation has been updated on https://github.com/wundergraph/docs-website.
  • I have read the Contributors Guide.

Open Source AI Manifesto

This project follows the principles of the Open Source AI Manifesto. Please ensure your contribution aligns with its principles.

Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Implements IdP-aware namespace access gating: adds LoginMethod/OIDC provider and namespace-SSO proto types and RPCs, DB schema and repositories for namespace SSO mappings, resolves login method from identity_provider claims, computes per-session allowed namespaces, enforces an IdP allowlist in RBAC and queries, and adds admin UI for mappings.

Changes

Multi-Provider SSO Namespace Access Gating

Layer / File(s) Summary
Protobuf Contracts and Generated Code
proto/wg/cosmo/platform/v1/platform.proto, connect/src/wg/cosmo/platform/v1/platform*.ts, connect/src/wg/cosmo/platform/v1/platform_pb.ts
LoginMethod message and enum added to WhoAmIResponse; OIDCProvider, ListOIDCProvidersRequest/Response introduced; GetOIDCProviderRequest, DeleteOIDCProviderRequest, UpdateIDPMappersRequest now include provider id field; new GetNamespaceSSOMapping*, NamespaceSSOMapping, UpdateNamespaceSSOMapping* messages and corresponding PlatformService RPCs; Connect Query and client bindings generated for new RPC methods.
Database Schema and Migrations
controlplane/migrations/0139_nappy_fallen_one.sql, controlplane/migrations/meta/_journal.json, controlplane/src/db/schema.ts
New namespace_sso_providers table with namespace/provider FK constraints, XOR check between ssoProviderId and isPasswordLogin, and unique partial indexes; sessions.idp_alias column added; oidc_providers.created_at timestamp added; Drizzle ORM schema updated to match.
Core Types and Configuration
controlplane/src/types/index.ts, controlplane/src/db/models.ts, docker/keycloak/realm.json
LoginMethod union type added for sso/password/api-key variants; AuthContext and UserInfoEndpointResponse extended with identity_provider claim; GraphCompositionDTO includes targetId; audit types updated for namespace_sso_mapping; Keycloak realm profile scope adds identity_provider OIDC protocol mapper.
Authentication and Login Method Resolution
controlplane/src/core/auth-utils.ts, controlplane/src/core/controllers/auth.ts, controlplane/src/core/services/WebSessionAuthenticator.ts, controlplane/src/core/services/AccessTokenAuthenticator.ts, controlplane/src/core/services/ApiKeyAuthenticator.ts, controlplane/src/core/services/Authentication.ts
Session creation extracts identity_provider claim from idToken into idpAlias for persistence; /session endpoint derives loginMethod from idpAlias via OIDC provider lookup; WebSessionAuthenticator, AccessTokenAuthenticator, ApiKeyAuthenticator all populate loginMethod in auth context; Authentication service caches per-sessionId and computes idpAllowedNamespaceIds via NamespaceSsoMappingRepository.
RBAC Evaluator and Authorization Gating
controlplane/src/core/services/RBACEvaluator.ts, controlplane/src/core/services/Authorization.ts
RBACEvaluator adds optional idpAllowedNamespaceIds allowlist; all permission-checking methods (canCreate*, hasFederatedGraphReadAccess, etc.) additionally enforce IdP namespace gate via isAllowedByIdpGate; Authorization service gates admin/developer operations on federated graphs and subgraphs by namespace membership in the IdP allowlist.
Repositories with IdP Namespace Gating
controlplane/src/core/repositories/NamespaceSsoMappingRepository.ts, controlplane/src/core/repositories/OidcRepository.ts, controlplane/src/core/repositories/NamespaceRepository.ts, controlplane/src/core/repositories/FederatedGraphRepository.ts, controlplane/src/core/repositories/SubgraphRepository.ts, controlplane/src/core/repositories/FeatureFlagRepository.ts, controlplane/src/core/repositories/GraphCompositionRepository.ts, controlplane/src/core/repositories/UserRepository.ts
NamespaceSsoMappingRepository (new) manages SSO provider-to-namespace mappings and computes allowedNamespaceIds by login method; OidcRepository refactored to support multi-provider org lookups, id-scoped lookup, alias-scoped lookup; namespace/federated-graph/subgraph/feature-flag repos apply IdP allowlist gates to queries; GraphCompositionRepository exposes targetId.
Handler Routes with RBAC and SSO APIs
controlplane/src/core/bufservices/namespace/{getNamespaceSSOMapping,updateNamespaceSSOMapping}.ts, controlplane/src/core/bufservices/sso/listOIDCProviders.ts, controlplane/src/core/bufservices/PlatformService.ts, analytics *.ts, federated-graph *.ts, proposal *.ts, sso *.ts, org *.ts, persisted-operation *.ts, cache-warmer *.ts, user *.ts
New handlers for namespace SSO mapping retrieval/update and OIDC provider listing with org-admin authorization; RBAC guards added to 20+ existing analytics/graph/proposal handlers (hasFederatedGraphReadAccess, hasNamespaceReadAccess); OIDC handlers (get, delete, updateIDPMappers) updated to require provider id; organization group handlers refactored for multi-provider OIDC mapper management; handlers wired into PlatformService; build-server.ts injects OidcRepository and NamespaceSsoMappingRepository into auth stack.
Studio Frontend: Login Method Display and Namespace SSO Configuration
studio/src/pages/[organizationSlug]/namespace-sso.tsx, studio/src/pages/[organizationSlug]/settings.tsx, studio/src/components/app-provider.tsx, studio/src/components/dashboard/namespace-gate-empty-state.tsx, studio/src/components/dashboard/namespace-selector.tsx, studio/src/components/layout/dashboard-layout.tsx, studio/src/components/user-menu.tsx
New namespace-sso.tsx page with two-pane layout: namespace list and SSO mapping detail editor (password login toggle, provider selection, dirty form tracking, mutation save); settings.tsx refactored for multi-provider OIDC management with provider cards, connect dialog, and mapper editing; namespace-gate-empty-state explains gated access via login method; namespace-selector shows "No access" when gated; user-menu displays login method label; dashboard-layout detects namespace-scoped routes and shows empty state when no namespaces accessible; app-provider syncs LoginMethod from session.

🎯 4 (Complex) | ⏱️ ~75 minutes

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 20, 2026

Router-nonroot image scan passed

✅ No security vulnerabilities found in image:

ghcr.io/wundergraph/cosmo/router:sha-5db5b585747d1f43025de4fd38f02928bd62ad93-nonroot

@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

❌ Patch coverage is 31.84358% with 1220 lines in your changes missing coverage. Please review.
✅ Project coverage is 40.79%. Comparing base (d211459) to head (385482a).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
studio/src/pages/[organizationSlug]/settings.tsx 0.00% 385 Missing ⚠️
...dio/src/pages/[organizationSlug]/namespace-sso.tsx 0.00% 283 Missing and 1 partial ⚠️
studio/src/components/ui/multi-select.tsx 0.00% 112 Missing and 1 partial ⚠️
...omponents/namespace-sso/namespace-mapping-rows.tsx 0.00% 70 Missing and 1 partial ⚠️
...lplane/src/core/bufservices/organization/whoAmI.ts 0.00% 46 Missing ⚠️
controlplane/src/core/util.ts 40.90% 39 Missing ⚠️
studio/src/components/layout/dashboard-layout.tsx 0.00% 29 Missing and 1 partial ⚠️
...io/src/components/dashboard/namespace-selector.tsx 0.00% 28 Missing ⚠️
controlplane/src/core/controllers/auth.ts 10.00% 27 Missing ⚠️
...omponents/dashboard/namespace-gate-empty-state.tsx 0.00% 18 Missing and 1 partial ⚠️
... and 40 more

❌ Your patch check has failed because the patch coverage (31.84%) is below the target coverage (90.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@             Coverage Diff             @@
##             main    #2876       +/-   ##
===========================================
- Coverage   66.24%   40.79%   -25.45%     
===========================================
  Files         258     1037      +779     
  Lines       27056   131072   +104016     
  Branches        0     6173     +6173     
===========================================
+ Hits        17923    53473    +35550     
- Misses       7720    75827    +68107     
- Partials     1413     1772      +359     
Files with missing lines Coverage Δ
...ntrolplane/src/core/bufservices/PlatformService.ts 83.35% <100.00%> (ø)
...c/core/bufservices/feature-flag/getFeatureFlags.ts 100.00% <100.00%> (ø)
.../bufservices/federated-graph/moveFederatedGraph.ts 86.11% <100.00%> (ø)
...ufservices/organization/deleteOrganizationGroup.ts 88.81% <100.00%> (ø)
...ane/src/core/bufservices/sso/createOIDCProvider.ts 85.00% <ø> (ø)
...lplane/src/core/bufservices/sso/getOIDCProvider.ts 100.00% <100.00%> (ø)
...lane/src/core/bufservices/sso/listOIDCProviders.ts 100.00% <100.00%> (ø)
...plane/src/core/bufservices/sso/updateIDPMappers.ts 90.00% <100.00%> (ø)
.../src/core/bufservices/user/updateOrgMemberGroup.ts 71.11% <100.00%> (ø)
controlplane/src/core/build-server.ts 74.50% <100.00%> (ø)
... and 58 more

... and 734 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
controlplane/src/core/bufservices/user/updateOrgMemberGroup.ts (1)

63-88: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keycloak client authentication happens after the SSO user checks.

The loop at lines 68-85 calls opts.keycloakClient.client.users.find() for each provider, but opts.keycloakClient.authenticateClient() is only called at line 88, after the loop. This may cause the Keycloak calls inside the loop to fail if the client token isn't already valid.

Consider moving the authentication call before the loop:

🔧 Proposed fix
       // Ensure that the organization member has not signed in with SSO via any
       // of the org's configured providers.
+      await opts.keycloakClient.authenticateClient();
+
       const providers = await oidcRepo.listOidcProvidersByOrganizationId({
         organizationId: authContext.organizationId,
       });
       for (const provider of providers) {
         // checking if the user has logged in using the sso
         const ssoUser = await opts.keycloakClient.client.users.find({
           realm: opts.keycloakRealm,
           email: orgMember.email,
           exact: true,
           idpAlias: provider.alias,
         });

         if (ssoUser.length > 0) {
           return {
             response: {
               code: EnumStatusCode.ERR,
               details: 'User has logged in using the OIDC provider. Please update the group using the provider.',
             },
           };
         }
       }

       // Retrieve the Keycloak user
-      await opts.keycloakClient.authenticateClient();

       const users = await opts.keycloakClient.client.users.find({
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@controlplane/src/core/bufservices/user/updateOrgMemberGroup.ts` around lines
63 - 88, The Keycloak client is authenticated after you call
opts.keycloakClient.client.users.find() inside the providers loop (after
listOidcProvidersByOrganizationId), which can cause those calls to fail; fix it
by calling and awaiting opts.keycloakClient.authenticateClient() before entering
the for (const provider of providers) loop so the client has a valid token, and
keep the existing find calls (client.users.find) unchanged; also propagate or
handle any authentication errors from authenticateClient() before proceeding.
🧹 Nitpick comments (2)
controlplane/src/core/services/RBACEvaluator.ts (1)

115-117: 💤 Low value

Minor: Redundant IdP gate check in canCreateContract.

canCreateFederatedGraph already calls isAllowedByIdpGate, so the additional check on line 116 is redundant. This doesn't cause incorrect behavior but adds unnecessary computation.

♻️ Suggested simplification
   canCreateContract(namespace: Namespace) {
-    return this.canCreateFederatedGraph(namespace) && this.isAllowedByIdpGate(namespace.id);
+    return this.canCreateFederatedGraph(namespace);
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@controlplane/src/core/services/RBACEvaluator.ts` around lines 115 - 117,
canCreateContract currently performs an extra isAllowedByIdpGate check despite
canCreateFederatedGraph already invoking isAllowedByIdpGate; remove the
redundant check from canCreateContract so it simply returns the result of
canCreateFederatedGraph(namespace) to avoid duplicate computation while
preserving behavior (refer to the canCreateContract, canCreateFederatedGraph,
and isAllowedByIdpGate symbols and the Namespace parameter).
controlplane/src/core/bufservices/organization/whoAmI.ts (1)

4-9: 💤 Low value

Static analysis false positive for generated protobuf types.

The linter flags LoginMethod_Type for not being in camelCase, but this identifier is auto-generated from the protobuf definitions and cannot be renamed here. Consider adding a lint suppression comment if this causes CI failures, or configure the linter to ignore generated import identifiers.

+// eslint-disable-next-line `@typescript-eslint/naming-convention`
 import {
   LoginMethod,
   LoginMethod_Type,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@controlplane/src/core/bufservices/organization/whoAmI.ts` around lines 4 - 9,
The import brings in auto-generated protobuf identifiers like LoginMethod_Type
which trigger the linter's camelCase rule; add a local lint suppression so the
generated name is allowed: place an ESLint/TSLint disable comment immediately
above the import line (targeting the naming-convention/camelcase rule) or add a
one-line disable for the specific rule, referencing the imported symbol
LoginMethod_Type to make it clear why the rule is disabled; ensure the comment
is minimal and scoped (not file-wide) so only the generated import is exempted.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@controlplane/src/core/bufservices/sso/deleteOIDCProvider.ts`:
- Around line 46-53: Move the request validation for req.id to run before any
Keycloak client authentication/initialization so invalid input returns
ERR_BAD_REQUEST deterministically; specifically, in deleteOIDCProvider (and
before any calls to getKeycloakClient / keycloakAdminClient.authenticate or
usage of variables like keycloakClient/keycloakAdminClient), check if (!req.id)
and return the ERR_BAD_REQUEST response immediately, then proceed to
create/authenticate the Keycloak client only after validation succeeds.

In `@controlplane/src/core/repositories/NamespaceSsoMappingRepository.ts`:
- Around line 70-81: The getMapping method is declared async but doesn't await
the database promise; remove the unnecessary async keyword from the getMapping
declaration (or alternatively add an await before
this.db.select(...).from(...).where(...).execute()) so the function either
returns the promise directly or properly awaits it; update the getMapping
signature and keep the existing query body referencing namespaceSsoProviders and
eq(namespaceSsoProviders.namespaceId, input.namespaceId).

In `@controlplane/src/core/repositories/OidcRepository.ts`:
- Around line 32-39: The method listOidcProvidersByOrganizationId is declared
async but does not use await; remove the unnecessary async modifier (or
alternatively await the DB promise) to fix the lint warning—update the method
signature in OidcRepository (and mirror the same fix pattern used in
NamespaceSsoMappingRepository) so it returns the DB query promise directly
without async, or add an await before this.db.select(...).execute() if you
prefer an awaited result.

In `@proto/wg/cosmo/platform/v1/platform.proto`:
- Around line 1896-1898: Update the GetOIDCProviderRequest (and analogous
messages at the other locations) to make the id field optional (i.e., mark it as
optional/allow empty) in the proto definition for message GetOIDCProviderRequest
and the similar messages at lines noted, then change the server handlers
GetOIDCProvider, DeleteOIDCProvider, and UpdateIDPMappers to tolerate a missing
id by implementing fallback resolution: if request.id is empty, try to infer the
provider id from the authenticated organization context (or from a single
default provider for that org) and only return a clear ERR_BAD_REQUEST when both
the id is missing and no unique provider can be resolved; ensure validation
error messages explicitly state when an id is required versus when a provider
could not be inferred.
- Around line 3100-3104: Change the UpdateNamespaceSSOMappingRequest proto so
allow_password_login is declared as "optional bool allow_password_login = 3;"
instead of plain bool, and then update the handler that processes
UpdateNamespaceSSOMappingRequest to check the presence of allow_password_login
(i.e., whether it is set/defined) before calling setMapping(); only pass a value
to setMapping() when the field is present (treat absent as “no change”), and
preserve existing behavior for explicit true/false inputs so setMapping()
continues to be called with explicit values when provided.

In `@studio/src/components/dashboard/namespace-selector.tsx`:
- Around line 91-100: The trigger hides the namespace label when
isViewingGraphOrSubgraph is true, which leaves only the caret visible even when
hasNoAccess is true; update the render logic in namespace-selector.tsx so that
when hasNoAccess is true you still render displayName (e.g., "No access" or the
existing displayName) even if isViewingGraphOrSubgraph is true—adjust the
conditional around the span that uses truncateNamespace, hasNoAccess and
displayName so it renders whenever hasNoAccess is true OR
isViewingGraphOrSubgraph is false, and ensure the className still applies
hasNoAccess styling.

In `@studio/src/components/user-menu.tsx`:
- Line 85: The SSO label currently uses loginMethod.ssoProviderName ||
loginMethod.ssoAlias || '' which can produce an empty string; update the logic
that sets ssoLabel (and the similar logic around lines 108-111) to provide a
fallback like 'SSO' instead of ''. For example, change the expression that
defines ssoLabel in component user-menu.tsx to use loginMethod.ssoProviderName
|| loginMethod.ssoAlias || 'SSO' (and apply the same fallback where the other
SSO display label is computed) so the UI never renders "Logged in via " with a
blank provider.

---

Outside diff comments:
In `@controlplane/src/core/bufservices/user/updateOrgMemberGroup.ts`:
- Around line 63-88: The Keycloak client is authenticated after you call
opts.keycloakClient.client.users.find() inside the providers loop (after
listOidcProvidersByOrganizationId), which can cause those calls to fail; fix it
by calling and awaiting opts.keycloakClient.authenticateClient() before entering
the for (const provider of providers) loop so the client has a valid token, and
keep the existing find calls (client.users.find) unchanged; also propagate or
handle any authentication errors from authenticateClient() before proceeding.

---

Nitpick comments:
In `@controlplane/src/core/bufservices/organization/whoAmI.ts`:
- Around line 4-9: The import brings in auto-generated protobuf identifiers like
LoginMethod_Type which trigger the linter's camelCase rule; add a local lint
suppression so the generated name is allowed: place an ESLint/TSLint disable
comment immediately above the import line (targeting the
naming-convention/camelcase rule) or add a one-line disable for the specific
rule, referencing the imported symbol LoginMethod_Type to make it clear why the
rule is disabled; ensure the comment is minimal and scoped (not file-wide) so
only the generated import is exempted.

In `@controlplane/src/core/services/RBACEvaluator.ts`:
- Around line 115-117: canCreateContract currently performs an extra
isAllowedByIdpGate check despite canCreateFederatedGraph already invoking
isAllowedByIdpGate; remove the redundant check from canCreateContract so it
simply returns the result of canCreateFederatedGraph(namespace) to avoid
duplicate computation while preserving behavior (refer to the canCreateContract,
canCreateFederatedGraph, and isAllowedByIdpGate symbols and the Namespace
parameter).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 300c6e7a-cd0b-4e45-bdb0-6e81f7d163be

📥 Commits

Reviewing files that changed from the base of the PR and between 8acd38f and 7011ecf.

⛔ Files ignored due to path filters (2)
  • connect-go/gen/proto/wg/cosmo/platform/v1/platform.pb.go is excluded by !**/*.pb.go, !**/gen/**
  • connect-go/gen/proto/wg/cosmo/platform/v1/platformv1connect/platform.connect.go is excluded by !**/gen/**
📒 Files selected for processing (71)
  • connect/src/wg/cosmo/platform/v1/platform-PlatformService_connectquery.ts
  • connect/src/wg/cosmo/platform/v1/platform_connect.ts
  • connect/src/wg/cosmo/platform/v1/platform_pb.ts
  • controlplane/migrations/0139_nappy_fallen_one.sql
  • controlplane/migrations/meta/0139_snapshot.json
  • controlplane/migrations/meta/_journal.json
  • controlplane/src/core/auth-utils.ts
  • controlplane/src/core/bufservices/PlatformService.ts
  • controlplane/src/core/bufservices/analytics/getAnalyticsView.ts
  • controlplane/src/core/bufservices/analytics/getDashboardAnalyticsView.ts
  • controlplane/src/core/bufservices/analytics/getFieldUsage.ts
  • controlplane/src/core/bufservices/analytics/getGraphMetrics.ts
  • controlplane/src/core/bufservices/analytics/getMetricsErrorRate.ts
  • controlplane/src/core/bufservices/analytics/getOperationClients.ts
  • controlplane/src/core/bufservices/analytics/getOperationContent.ts
  • controlplane/src/core/bufservices/analytics/getOperationDeprecatedFields.ts
  • controlplane/src/core/bufservices/analytics/getOperations.ts
  • controlplane/src/core/bufservices/analytics/getTrace.ts
  • controlplane/src/core/bufservices/cache-warmer/computeCacheWarmerOperations.ts
  • controlplane/src/core/bufservices/cache-warmer/configureCacheWarmer.ts
  • controlplane/src/core/bufservices/feature-flag/getFeatureFlags.ts
  • controlplane/src/core/bufservices/federated-graph/getClientsFromAnalytics.ts
  • controlplane/src/core/bufservices/federated-graph/getCompositionDetails.ts
  • controlplane/src/core/bufservices/federated-graph/migrateFromApollo.ts
  • controlplane/src/core/bufservices/federated-graph/moveFederatedGraph.ts
  • controlplane/src/core/bufservices/namespace/getNamespaceSSOMapping.ts
  • controlplane/src/core/bufservices/namespace/updateNamespaceSSOMapping.ts
  • controlplane/src/core/bufservices/organization/deleteOrganizationGroup.ts
  • controlplane/src/core/bufservices/organization/getOrganizationGroups.ts
  • controlplane/src/core/bufservices/organization/whoAmI.ts
  • controlplane/src/core/bufservices/persisted-operation/getClients.ts
  • controlplane/src/core/bufservices/persisted-operation/getPersistedOperations.ts
  • controlplane/src/core/bufservices/proposal/getNamespaceProposalConfig.ts
  • controlplane/src/core/bufservices/proposal/getProposal.ts
  • controlplane/src/core/bufservices/proposal/getProposalChecks.ts
  • controlplane/src/core/bufservices/schema-version/getChangelogBySchemaVersion.ts
  • controlplane/src/core/bufservices/sso/createOIDCProvider.ts
  • controlplane/src/core/bufservices/sso/deleteOIDCProvider.ts
  • controlplane/src/core/bufservices/sso/getOIDCProvider.ts
  • controlplane/src/core/bufservices/sso/listOIDCProviders.ts
  • controlplane/src/core/bufservices/sso/updateIDPMappers.ts
  • controlplane/src/core/bufservices/user/updateOrgMemberGroup.ts
  • controlplane/src/core/build-server.ts
  • controlplane/src/core/controllers/auth.ts
  • controlplane/src/core/repositories/FeatureFlagRepository.ts
  • controlplane/src/core/repositories/FederatedGraphRepository.ts
  • controlplane/src/core/repositories/GraphCompositionRepository.ts
  • controlplane/src/core/repositories/NamespaceRepository.ts
  • controlplane/src/core/repositories/NamespaceSsoMappingRepository.ts
  • controlplane/src/core/repositories/OidcRepository.ts
  • controlplane/src/core/repositories/SubgraphRepository.ts
  • controlplane/src/core/repositories/UserRepository.ts
  • controlplane/src/core/services/AccessTokenAuthenticator.ts
  • controlplane/src/core/services/ApiKeyAuthenticator.ts
  • controlplane/src/core/services/Authentication.ts
  • controlplane/src/core/services/Authorization.ts
  • controlplane/src/core/services/RBACEvaluator.ts
  • controlplane/src/core/services/WebSessionAuthenticator.ts
  • controlplane/src/core/workers/DeleteOrganizationWorker.ts
  • controlplane/src/db/models.ts
  • controlplane/src/db/schema.ts
  • controlplane/src/types/index.ts
  • docker/keycloak/realm.json
  • proto/wg/cosmo/platform/v1/platform.proto
  • studio/src/components/app-provider.tsx
  • studio/src/components/dashboard/namespace-gate-empty-state.tsx
  • studio/src/components/dashboard/namespace-selector.tsx
  • studio/src/components/layout/dashboard-layout.tsx
  • studio/src/components/user-menu.tsx
  • studio/src/pages/[organizationSlug]/namespace-sso.tsx
  • studio/src/pages/[organizationSlug]/settings.tsx
💤 Files with no reviewable changes (1)
  • controlplane/src/core/bufservices/sso/createOIDCProvider.ts

Comment thread controlplane/src/core/bufservices/sso/deleteOIDCProvider.ts Outdated
Comment thread controlplane/src/core/repositories/NamespaceSsoMappingRepository.ts Outdated
Comment thread controlplane/src/core/repositories/OidcRepository.ts Outdated
Comment thread proto/wg/cosmo/platform/v1/platform.proto
Comment thread proto/wg/cosmo/platform/v1/platform.proto Outdated
Comment thread studio/src/components/dashboard/namespace-selector.tsx Outdated
Comment thread studio/src/components/user-menu.tsx Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
controlplane/src/core/bufservices/organization/whoAmI.ts (1)

5-6: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix ESLint camelcase error for protobuf-generated import.

The pipeline is failing because LoginMethod_Type violates the camelcase rule. Since this is a protobuf-generated identifier that cannot be renamed, add an ESLint disable comment for this import.

🔧 Proposed fix
 import {
   LoginMethod,
+  // eslint-disable-next-line camelcase
   LoginMethod_Type,
   WhoAmIRequest,
   WhoAmIResponse,
 } from '`@wundergraph/cosmo-connect/dist/platform/v1/platform_pb`';

Alternatively, disable inline at each usage site if the import-level disable doesn't work:

// eslint-disable-next-line camelcase
type: LoginMethod_Type.LOGIN_METHOD_TYPE_SSO,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@controlplane/src/core/bufservices/organization/whoAmI.ts` around lines 5 - 6,
The import of the protobuf-generated identifier LoginMethod_Type violates
ESLint's camelcase rule; fix it by adding an inline ESLint disable comment for
camelcase on the import line that brings in LoginMethod_Type (i.e., adjust the
import that includes LoginMethod and LoginMethod_Type to include "//
eslint-disable-next-line camelcase" immediately above it) so the generated
identifier is allowed without renaming; if that import-level disable doesn't
resolve linting, alternatively add "// eslint-disable-next-line camelcase" at
the specific usage sites where LoginMethod_Type is referenced (e.g., where type:
LoginMethod_Type.LOGIN_METHOD_TYPE_SSO is used).
🧹 Nitpick comments (1)
controlplane/src/core/bufservices/organization/whoAmI.ts (1)

44-88: 💤 Low value

Inconsistent formatting in switch cases.

The switch statement has unusual blank lines before break; statements (lines 57-58, 67-68, 77-78). This appears to be inconsistent formatting that should be cleaned up for readability.

✨ Suggested formatting
     case 'sso': {
       const oidcRepo = new OidcRepository(opts.db);
       const provider = await oidcRepo.getOidcProviderById({
         id: lm.ssoProviderId,
         organizationId: authContext.organizationId,
       });
       loginMethod = {
         type: LoginMethod_Type.LOGIN_METHOD_TYPE_SSO,
         ssoProviderId: lm.ssoProviderId,
         ssoProviderName: provider?.name ?? '',
         ssoAlias: lm.alias,
       };
-    
       break;
     }
     case 'password': {
       loginMethod = {
         type: LoginMethod_Type.LOGIN_METHOD_TYPE_PASSWORD,
         ssoProviderId: '',
         ssoProviderName: '',
         ssoAlias: '',
       };
-    
       break;
     }
     case 'api-key': {
       loginMethod = {
         type: LoginMethod_Type.LOGIN_METHOD_TYPE_API_KEY,
         ssoProviderId: '',
         ssoProviderName: '',
         ssoAlias: '',
       };
-    
       break;
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@controlplane/src/core/bufservices/organization/whoAmI.ts` around lines 44 -
88, The switch on lm?.type in whoAmI.ts (cases handling 'sso', 'password',
'api-key', and default that set loginMethod using LoginMethod_Type and
OidcRepository/provider) contains stray blank lines immediately before each
break; remove those blank lines so each case ends directly with the break
statement, ensure consistent spacing/indentation within each case (no extra
vertical gaps), and run the project formatter to normalize the file.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@controlplane/src/core/bufservices/organization/whoAmI.ts`:
- Around line 5-6: The import of the protobuf-generated identifier
LoginMethod_Type violates ESLint's camelcase rule; fix it by adding an inline
ESLint disable comment for camelcase on the import line that brings in
LoginMethod_Type (i.e., adjust the import that includes LoginMethod and
LoginMethod_Type to include "// eslint-disable-next-line camelcase" immediately
above it) so the generated identifier is allowed without renaming; if that
import-level disable doesn't resolve linting, alternatively add "//
eslint-disable-next-line camelcase" at the specific usage sites where
LoginMethod_Type is referenced (e.g., where type:
LoginMethod_Type.LOGIN_METHOD_TYPE_SSO is used).

---

Nitpick comments:
In `@controlplane/src/core/bufservices/organization/whoAmI.ts`:
- Around line 44-88: The switch on lm?.type in whoAmI.ts (cases handling 'sso',
'password', 'api-key', and default that set loginMethod using LoginMethod_Type
and OidcRepository/provider) contains stray blank lines immediately before each
break; remove those blank lines so each case ends directly with the break
statement, ensure consistent spacing/indentation within each case (no extra
vertical gaps), and run the project formatter to normalize the file.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3529a86f-cc01-4aa6-934b-722a4f739841

📥 Commits

Reviewing files that changed from the base of the PR and between 7011ecf and 4d69a9e.

📒 Files selected for processing (4)
  • controlplane/src/core/bufservices/organization/whoAmI.ts
  • studio/src/components/user-menu.tsx
  • studio/src/pages/[organizationSlug]/namespace-sso.tsx
  • studio/src/pages/[organizationSlug]/settings.tsx

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
controlplane/src/core/services/RBACEvaluator.ts (1)

115-117: 💤 Low value

Redundant IdP gate check in canCreateContract.

canCreateFederatedGraph already includes the isAllowedByIdpGate check, making the additional call here redundant.

♻️ Suggested simplification
 canCreateContract(namespace: Namespace) {
-  return this.canCreateFederatedGraph(namespace) && this.isAllowedByIdpGate(namespace.id);
+  return this.canCreateFederatedGraph(namespace);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@controlplane/src/core/services/RBACEvaluator.ts` around lines 115 - 117, The
canCreateContract method redundantly calls isAllowedByIdpGate because
canCreateFederatedGraph already performs that check; simplify canCreateContract
by returning only the result of canCreateFederatedGraph(namespace) (keep the
Namespace parameter) and remove the extra isAllowedByIdpGate(namespace.id)
invocation so the logic isn’t duplicated in canCreateContract, referencing the
canCreateContract, canCreateFederatedGraph, and isAllowedByIdpGate symbols for
location.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@controlplane/src/core/services/RBACEvaluator.ts`:
- Around line 115-117: The canCreateContract method redundantly calls
isAllowedByIdpGate because canCreateFederatedGraph already performs that check;
simplify canCreateContract by returning only the result of
canCreateFederatedGraph(namespace) (keep the Namespace parameter) and remove the
extra isAllowedByIdpGate(namespace.id) invocation so the logic isn’t duplicated
in canCreateContract, referencing the canCreateContract,
canCreateFederatedGraph, and isAllowedByIdpGate symbols for location.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b408b318-6432-4fd9-9105-909569ce3f6e

📥 Commits

Reviewing files that changed from the base of the PR and between 74c49c9 and 09e262e.

📒 Files selected for processing (5)
  • controlplane/src/core/bufservices/federated-graph/moveFederatedGraph.ts
  • controlplane/src/core/bufservices/organization/whoAmI.ts
  • controlplane/src/core/bufservices/sso/listOIDCProviders.ts
  • controlplane/src/core/services/RBACEvaluator.ts
  • controlplane/src/db/schema.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@controlplane/test/oidc-provider.test.ts`:
- Around line 42-45: Replace the non-deterministic providers[0] selection with a
deterministic lookup: after calling client.listOIDCProviders use
Array.prototype.find to locate the provider by a known unique attribute (e.g.,
provider.name or createdProvider.id) and assert it exists, then pass that
provider.id into client.getOIDCProvider; update the same pattern for the other
occurrences (the blocks that call client.listOIDCProviders and then index
providers) so each test selects by name or by the id returned when creating the
provider rather than using providers[0].
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c54a7ace-fd6a-4e38-9e0c-6a8b77a832aa

📥 Commits

Reviewing files that changed from the base of the PR and between 09e262e and 563e720.

📒 Files selected for processing (1)
  • controlplane/test/oidc-provider.test.ts

Comment thread controlplane/test/oidc-provider.test.ts
Comment thread controlplane/src/core/controllers/auth.ts
Comment thread controlplane/src/core/repositories/GraphCompositionRepository.ts
Copy link
Copy Markdown
Contributor

@comatory comatory left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I have few suggestions but they're all related to readability and structure. Otherwise let me know and I'll test this manually and do another pass at this as soon as I can.

Comment thread controlplane/src/core/repositories/SubgraphRepository.ts Outdated
Comment thread controlplane/src/core/services/Authentication.ts Outdated
Comment thread controlplane/src/core/repositories/NamespaceSsoMappingRepository.ts
Comment thread studio/src/components/dashboard/namespace-selector.tsx Outdated
Comment thread studio/src/components/layout/dashboard-layout.tsx
Comment thread studio/src/pages/[organizationSlug]/settings.tsx
Comment thread studio/src/pages/[organizationSlug]/namespace-sso.tsx Outdated
Comment thread studio/src/pages/[organizationSlug]/namespace-sso.tsx Outdated
Comment thread studio/src/pages/[organizationSlug]/namespace-sso.tsx Outdated
Comment thread studio/src/pages/[organizationSlug]/namespace-sso.tsx Outdated
@github-actions

This comment has been minimized.

…mappings

- Added `listNamespaceSSOMappings` function to retrieve SSO mappings for restricted namespaces.
- Updated `PlatformService` to include the new API endpoint.
- Created `listNamespaceSSOMappings.ts` in the namespace service to handle the logic.
- Modified `NamespaceSsoMappingRepository` to support listing mappings with RBAC checks.
- Updated tests to validate the new functionality.
- Refactored the namespace SSO mapping page to utilize the new API, replacing the previous mapping retrieval logic.
- Introduced `NamespaceMappingRows` component for managing SSO mappings in the UI.
- Added a new `MultiSelect` component for selecting allowed login methods.
…space SSO mappings

- Introduced new LoginMethodType for social logins and updated related types.
- Enhanced updateNamespaceSSOMappings to handle Google and GitHub login options.
- Updated NamespaceSsoMappingRepository to manage new login methods.
- Modified whoAmI and auth controllers to accommodate social login methods.
- Updated UI components to reflect changes in login methods and display appropriate labels.
- Added tests to ensure correct behavior for social login mappings and access control.
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

.where(and(...conditions))
.execute();

type Entry = {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd just inline it on L124. It's odd creating a standalone type in middle of the function body.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants